// 构造函数
function Mine(tr, td, mineNum) {
	this.tr = tr; // 行数
	this.td = td; // 列数
	this.mineNum = mineNum; // 雷的个数

	this.squares = []; // 存储所有方块的信息 它是一个二维数组 执行与列的顺序排放 存取都使用行列的形式
	this.tds = []; // 存取所有单元格的DOM
	this.surplusMine = mineNum; // 剩余雷的数量
	this.allRight = false; // 右击的小红旗是否全部是类雷 用来判断用户游戏是否成功

	this.parent = document.querySelector('.gameBox');
}
// 生成n个不重复的数字
Mine.prototype.randomNum = function () {
	var square = new Array(this.tr * this.td); // 创建一个空数组 数组长度等于格子数
	for (var i = 0; i < square.length; i++) {
		square[i] = i;
	}
	// 对数组进行随机排序
	square.sort(function () {
		return 0.5 - Math.random();
	})
	// 截取数组的前（雷的个数）个
	return square.slice(0, this.mineNum);
}
Mine.prototype.init = function () {
	// console.log(this.randomNum());
	var rn = this.randomNum(); // 雷的位置
	var n = 0; 
	for (var i = 0; i < this.tr; i++) {
		this.squares[i] = [];
		for (var j = 0; j < this.td; j++) {
			// n++;
			if (rn.indexOf(++n) != -1) {
				this.squares[i][j] = {type: 'mine', x: j, y: i};
			} else {
				this.squares[i][j] = {type: 'number', x: j, y: i, value: 0};
			}
		}
	}
	this.parent.innerHTML = '';
	this.parent.oncontextmenu = function () {
		return false;
	}
	document.querySelector('.mineNum').innerHTML = this.surplusMine;
	// console.log(this.squares);
	this.updateNum();
	this.createDom();
}
// 创建表格
Mine.prototype.createDom = function () {
	var This = this;
	var table = document.createElement('table');
	for (var i = 0; i < this.tr; i++) {
		var domTr = document.createElement('tr');
		this.tds[i] = [];
		for (var j = 0; j < this.td; j++) {
			var domTd = document.createElement('td');
			// domTd.innerHTML = '0';
			
			domTd.pos = [i, j];
			domTd.onmousedown = function () {
				This.play(event, this);
			}
			/*if (this.squares[i][j].type == 'mine') {
				domTd.className = 'mine';
			}
			if (this.squares[i][j].type == 'number') {
				domTd.innerHTML = this.squares[i][j].value;
			}*/
			this.tds[i][j] = domTd;
			domTr.appendChild(domTd);
		}
		table.appendChild(domTr);
	}
	this.parent.appendChild(table);
}
Mine.prototype.getAround = function (square) {
	var x = square.x;
	var y = square.y;
	var result = [];
	/*
		x-1,y-1	 x,y-1  x+1,y-1
		x-1,y	 x,y	x+1, y	
		x-1,y+1	 x,y+1  x+1,y+1
	*/
	for (var i = x - 1; i <= x + 1; i++) {
		for (var j = y - 1; j <= y + 1; j++) {
			if (
				i < 0 || // 超出了左边界
				j < 0 || // 超出了上边界
				i > this.td - 1 || // 超出了右边界
				j > this.tr - 1 || // 超出了下边界
				(i == x && j == y) || // 当前循环到的格子是自己
				this.squares[j][i].type == 'mine' // 周围的格子是个雷
				) {
				continue;
			}
			result.push([j,i]);
		}
	}
	return result;
}
// 更新所有的数字
Mine.prototype.updateNum = function () {
	for(var i = 0; i < this.tr; i++) {
		for (var j = 0; j < this.td; j++) {
			if (this.squares[i][j].type == 'number') {
				continue;
			}
			var num = this.getAround(this.squares[i][j]);
			for (var k = 0; k < num.length; k++) {
				/*
					num[i] = [0, 1];
					num[i][0] = 0;
					num[i][1] = 1;
				*/
				this.squares[num[k][0]][num[k][1]].value += 1;
			}
		}
	}
}

Mine.prototype.play = function (ev, obj) {
	var This = this;
	if (ev.which == 1 && obj.className != 'flag') { // 点击的是左键
		// console.log(obj);
		var curSquare = this.squares[obj.pos[0]][obj.pos[1]];
		// console.log(curSquare);
		var cl = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight'];
		if (curSquare.type == 'number') {
			// console.log('你点到数字了');
			obj.innerHTML = curSquare.value;
			obj.className = cl[curSquare.value];
			if (curSquare.value == 0) {
				obj.innerHTML = '';
				function getAllZero(square) {
					// 得到当前元素周围的所有元素
					var around = This.getAround(square);
					for (var i = 0; i < around.length; i++) {
						var x = around[i][0];
						var y = around[i][1];
						This.tds[x][y].className = cl[This.squares[x][y].value];
						// 如果周围的元素是0的话
						if (This.squares[x][y].value == 0) {
							// 对周围是0的元素进行递归
							// 防止重复递归
							if (!This.tds[x][y].check) {
								This.tds[x][y].check = true;
								getAllZero(This.squares[x][y]);
							}
						} else { 
							// 如果周围的元素不是0 直接显示数字
							This.tds[x][y].innerHTML = This.squares[x][y].value;
						}
					}
				}
				getAllZero(curSquare);
			}
		} else {
			// console.log('你点到雷了');
			this.gameOver(obj);
		}
	}
	if (ev.which == 3) {
		// 如果右击的是一个数字 那就不能点击
		if (obj.className && obj.className != 'flag') {
			return;
		}
		// 切换class
		obj.className = obj.className == 'flag' ? '' : 'flag';
		if (this.squares[obj.pos[0]][obj.pos[1]].type == 'mine') {
			// 用户标注的小红旗背后全是雷
			this.allRight = true;
		} else  {
			// 用户标注的小红旗背后有一个不是雷
			this.allRight = false;
		}

		if (obj.className == 'flag') {
			document.querySelector('.mineNum').innerHTML = --this.surplusMine;
		} else {
			document.querySelector('.mineNum').innerHTML = ++this.surplusMine;
		}

		if (this.surplusMine == 0) {
			// 剩余的雷数为0 表示用户以及标完小红旗了 这时候要判断是成功还是失败
			if (this.allRight) {
				alert('挑战成功！');
			} else {
				alert('挑战失败');
				this.gameOver();
			}
		}
	}
}

// 游戏失败函数
Mine.prototype.gameOver = function (clickTd) {
	/*
		1. 显示所有的雷
		2. 取消格子的点击事件
		3. 给点中的雷添加红色背景
	*/
	for (var i = 0; i < this.tr; i++) {
		for (var j = 0; j < this.td; j++) {
			if (this.squares[i][j].type == 'mine') {
				this.tds[i][j].className = 'mine';
			}
			this.tds[i][j].onmousedown = null;
		}
	}
	if (clickTd) {
		clickTd.style.backgroundColor = '#f00';
	}
}

// 上边button的功能
var btns = document.querySelectorAll('.level button');
var mine = null; // 用来存储生成的实例
var ln = 0; // 用来处理当前选中的状态
var arr = [[9, 9, 10], [16, 16, 40], [28, 28, 99]];

for (let i = 0; i < btns.length - 1; i++) {
	btns[i].onclick = function () {
		btns[ln].className = '';
		this.className = 'active';
		mine = new Mine(...arr[i]);
		mine.init();
		ln = i;
	}
}
btns[0].onclick();
btns[3].onclick = function () {
	mine.init();
	document.querySelector('.mineNum').innerHTML = mine.mineNum;
	mine.surplusMine = mine.mineNum;
}


/*var mine = new Mine(28, 28, 99);
mine.init();*/
// console.log(mine.getAround(mine.squares[0][0]));
